Powershell scripts/3rd party SIEM integration/EnableAlertsStreamingTo3rdPartySiem.ps1 (236 lines of code) (raw):

#Requires -Modules @{ ModuleName="Az.Resources"; ModuleVersion="5.2.0" } #Requires -Modules @{ ModuleName="Az.EventHub"; ModuleVersion="1.9.1" } #Requires -Modules @{ ModuleName="Az.Storage"; ModuleVersion="3.12.0" } <# .SYNOPSIS This script will create the required resources and configurations to stream alerts from Microsoft Defender for Cloud to 3rd party SIEM. .DESCRIPTION Streaming Microsoft Defender for Cloud security alerts to external SIEM solutions require setups on both Azure side and the 3rd party SIEM side. This script execute the required steps on Azure side and provide the information required to enable the connector on the SIEM side. .PARAMETER scope [mandatory] The scope to apply the continious export policy on .PARAMETER subscriptionId [mandatory] The Azure subscription id of the subscription the event hub will be created in. .PARAMETER resourceGroupName [mandatory] The resourceGroupName of the resource group the event hub and continious export will be created in. If no suce resource group exists the script will create it. .PARAMETER eventHubNamespaceName [mandatory] The name of the event hub namespace to create. .PARAMETER eventHubName [mandatory] The name of the event hub to create. .PARAMETER location [mandatory] The desired Azure region location for the resources. .PARAMETER siem [mandatory] The target SIEM, used to create the required resources for the specific SIEM. Current options are: Splunk, QRadar. .PARAMETER aadAppName The AAD app name to create to support streaming to Splunk. Must be passed if $siem=="Splunk" .PARAMETER storageName The storage account name to create to support streaming to QRadar. Must be passed if $siem=="QRadar" .EXAMPLE .\EnableAlertsStreamingTo3rdPartySiem.ps1 -scope `<Scope>` -subscriptionId `<Subscription Id>` -resourceGroupName `<RG Name>` -eventHubNamespaceName `<New event hub namespace name>` -eventHubName `<New event hub name>` -location `<Location>` -siem `<Splunk / QRadar>` -aadAppName `<New AAD application name>` -storageName `<New storage name>` .EXAMPLE .\EnableAlertsStreamingTo3rdPartySiem.ps1 -scope '' -subscriptionId 'f4cx1b69-dtgb-4ch6-6y6f-ea2e95373d3b' -resourceGroupName 'DefaultResourceGroup-WEU' -eventHubNamespaceName 'eventHubNamespace' -eventHubName 'eventHub' -location 'Central US' -siem 'Splunk' -aadAppName 'SplunkConnectorApp' .EXAMPLE .\EnableAlertsStreamingTo3rdPartySiem.ps1 -scope '' -subscriptionId 'f4cx1b69-dtgb-4ch6-6y6f-ea2e95373d3b' -resourceGroupName 'DefaultResourceGroup-WEU' --eventHubNamespaceName 'eventHubNamespace' -eventHubName 'eventHub' -location 'Central US' -siem 'QRadar' -storageName 'qradarconnectorstorage' .NOTES AUTHOR: Gal Grinblat - MDC ??? LASTEDIT: January 20, 2022 0.1 - 0.1 change log: Initial commit .LINK This script posted to and discussed at the following locations: https://github.com/Azure/Azure-Security-Center/tree/master/Powershell%20scripts #> # Prerequisites # Install-module Az # Install-module Az.Resources # Install-module Az.EventHub # Install-module Az.Storage [CmdletBinding()] param ( [Parameter(Mandatory)] [string]$scope, [Parameter(Mandatory)] [string]$subscriptionId, [Parameter(Mandatory)] [string]$resourceGroupName, [Parameter(Mandatory)] [string]$eventHubNamespaceName, [Parameter(Mandatory)] [string]$eventHubName, [Parameter(Mandatory)] [string]$location, [Parameter(Mandatory)] [ValidateSet("Splunk","QRadar")]$siem, [Parameter()] [string]$aadAppName, [Parameter()] [string]$storageName ) function CreateSplunkRelatedResources { param ( [Parameter(Mandatory)] [Microsoft.Azure.Commands.EventHub.Models.PSNamespaceAttributes]$eventHubNamespace, [Parameter(Mandatory)] [Microsoft.Azure.Commands.EventHub.Models.PSEventHubAttributes]$eventHub, [Parameter(Mandatory)] [string]$aadAppName ) # Create AAD app Write-Output "Create new AAD app" $app = New-AzADApplication -DisplayName $aadAppName Write-Debug "Create a service principal for the aad app" $servicePrincipal = New-AzADServicePrincipal -ApplicationId $app.AppId Write-Debug "Create a new password for the aad app" $appCred = New-AzADAppCredential -ApplicationId $app.AppId Write-Debug "Give the service principal access to read from the event hub" $roleDefinitionId = "a638d3c7-ab3a-418d-83e6-5f17a39d4fde" # Azure Event Hubs Data Receiver Write-Debug "Going to give $($servicePrincipal.Id) role definition id $roleDefinitionId on scope $eventHub.Id" New-AzRoleAssignment -ObjectId $servicePrincipal.Id -RoleDefinitionId $roleDefinitionId -Scope $eventHub.Id Write-Output "Requierd information for Splunk connection:" Write-Output "AAD app params:" Write-Output "Client ID: $($app.AppId)" Write-Output "Key (Client Secret): $($appCred.SecretText)" Write-Output "Tenant ID: $(Get-AzTenant)" Write-Output "Event Hub params:" Write-Output "Event Hub Namespace(FQDN): $($eventHubNamespace.ServiceBusEndpoint)" Write-Output "Event Hub Name: $($eventHub.Name)" Write-Output "Consumer Group: $($consumerGroup.Name)" } function CreateQRadatRelatedResources { param ( [Parameter(Mandatory)] [string]$resourceGroupName, [Parameter(Mandatory)] [string]$eventHubNamespaceName, [Parameter(Mandatory)] [string]$eventHubName, [Parameter(Mandatory)] [string]$location, [Parameter(Mandatory)] [string]$storageName ) Write-Output "Create new Event Hub listen policy for $eventHubName in $eventHubNamespaceName" $eventHubListenAccessPolicyName = "ContinuousExportListenPolicy" $ListenAuthRule = New-AzEventHubAuthorizationRule -ResourceGroupName $resourceGroupName -NamespaceName $eventHubNamespaceName -EventHubName $eventHubName -AuthorizationRuleName $eventHubListenAccessPolicyName -Rights Listen $eventHubConnectionString = Get-AzEventHubKey -ResourceGroupName $resourceGroupName -NamespaceName $eventHubNamespaceName -EventHub $eventHubName -Name $ListenAuthRule.Name | Select-Object PrimaryConnectionString Write-Output "Create new storage account" $storage = New-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageName -Location $location -SkuName Standard_LRS $storageKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageName)[0].Value $storageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=' + $storageName + ';AccountKey=' + $storageKey + ';EndpointSuffix=core.windows.net' Write-Output "Requierd information for Qradar connection:" Write-Output "Event Hub connection string: $($eventHubConnectionString.PrimaryConnectionString)" Write-Output "Storage account connection string: $storageConnectionString" Write-Output "Consumer Group: $($consumerGroup.Name)" } # Validate params if ($siem -eq "Splunk") { if ([string]::IsNullOrEmpty($aadAppName)) { Write-Error "When selecting Splunk as the SIEM type the aadAppName parameter is mandatory" Return } } if ($siem -eq "QRadar") { if ([string]::IsNullOrEmpty($storageName)) { Write-Error "When selecting QRadar as the SIEM type the storageName parameter is mandatory" Return } } Set-AzContext -SubscriptionId $subscriptionId -ErrorAction Break $eventHubSendAccessPolicyName = "ContinuousExportSendPolicy" # Continious Export section ## Create event hub Write-Output "Creating the continuous export target event hub..." Write-Debug "Check if resource group '$resourceGroupName' already exists..." $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName -ErrorVariable notPresent -ErrorAction SilentlyContinue if ( $notPresent) { Write-Debug "Resource group '$resourceGroupName' doesn't exists, creating it." $resourceGroup = New-AzResourceGroup -Name $resourceGroupName -Location $location } else { Write-Debug "Resource group already exists." } Write-Debug "Creating new Event Hub Namespace '$eventHubNamespaceName'" $eventHubNamespace = New-AzEventHubNamespace -ResourceGroupName $resourceGroupName -Name $eventHubNamespaceName -Location $location Write-Debug "Creating new Event Hub $eventHubName in $eventHubNamespaceName" $eventHub = New-AzEventHub -ResourceGroupName $resourceGroupName -NamespaceName $eventHubNamespaceName -Name $eventHubName -MessageRetentionInDays 1 Write-Debug "Creating new Event Hub send policy for $eventHubName in $eventHubNamespaceName" $SendAuthRule = New-AzEventHubAuthorizationRule -ResourceGroupName $resourceGroupName -NamespaceName $eventHubNamespaceName -EventHubName $eventHubName -AuthorizationRuleName $eventHubSendAccessPolicyName -Rights Send ## Enable continuous export (by policy) Write-Output "Creating new continuous export policy" $policyDef = Get-AzPolicyDefinition -Name cdfcce10-4578-4ecd-9703-530938e4abcb $PolicyParameterObject = @{ 'resourceGroupName' = $resourceGroupName 'resourceGroupLocation' = $location 'eventHubDetails' = $SendAuthRule.Id 'exportedDataTypes' = @('Security alerts') 'alertSeverities' = @('High', 'Medium', 'Low') } $policyAssignment = New-AzPolicyAssignment -Name "Continuous export policy" -PolicyDefinition $policyDef -Scope $scope -PolicyParameterObject $PolicyParameterObject -Location $location -AssignIdentity $roleDefinitionIds = $policyDef.Properties.policyRule.then.details.roleDefinitionIds $retryCount = 0 $policyRoleAssignmentSuccess = $true do { try { $roleDefinitionIds | ForEach-Object { $roleDefId = $_.Split("/") | Select-Object -Last 1 Write-Debug "Going to assign role definition id $roleDefId to service principal $($policyAssignment.Identity.PrincipalId) on scope $scope" New-AzRoleAssignment -Scope $scope -ObjectId $policyAssignment.Identity.PrincipalId -RoleDefinitionId $roleDefId -ErrorAction Stop $policyRoleAssignmentSuccess = $true break } } catch { if ($retryCount -gt 3) { $policyRoleAssignmentSuccess = $false break } Write-Debug "Failed to assign role difinition, will retry in 5 seconds" $retryCount++ Start-Sleep -Seconds 5 } } while ($retryCount -le 3) if ($policyRoleAssignmentSuccess) { $remediationJob = Start-AzPolicyRemediation -PolicyAssignmentId $policyAssignment.PolicyAssignmentId -Name "Initial assignment" -AsJob } # 3rd party siem region Write-Debug "Create new consumer group for event hub: $eventHubName" $siemConsumerGroupName = "Siem" $consumerGroup = New-AzEventHubConsumerGroup -ResourceGroupName $resourceGroupName -NamespaceName $eventHubNamespaceName -EventHubName $eventHubName -ConsumerGroupName $siemConsumerGroupName ## Splunk if ($siem -eq "Splunk") { CreateSplunkRelatedResources -eventHubNamespace $eventHubNamespace -eventhub $eventHub -aadAppName $aadAppName } ## QRadar else { CreateQRadatRelatedResources -resourceGroupName $resourceGroupName -eventHubNamespaceName $eventHubNamespaceName -eventHubName $eventHubName -location $location -storageName $storageName } if ($policyRoleAssignmentSuccess) { $remediationJob | Wait-Job $remediation = $remediationJob | Receive-Job if ($remediation.ProvisioningState -ne "Succeeded") { Write-Warning "The policy assignment failed" } } else { Write-Error "Failed to assign role difinition to the continuous export policy, the policy doesn't have the required permissions to remediate." Write-Error "To fix the role assignment try running the following command(s):" $roleDefinitionIds | ForEach-Object { $roleDefId = $_.Split("/") | Select-Object -Last 1 Write-Error "New-AzRoleAssignment -Scope $scope -ObjectId $policyAssignment.Identity.PrincipalId -RoleDefinitionId $roleDefId" } }